<!--
 * @Author: Dorange.Wang
 * @Date: 2021-04-19 16:05:49
 * @LastEditors: your name
 * @LastEditTime: 2021-09-10 17:48:12
 * @Description: file content
-->
<template>
  <el-dialog :visible="showVisible" center :show-close="false" width="600px">
    <div class="b g3 f16 tl" slot="title">
      <div class="ks-row-between pl15 pr15">
        <span>{{ isNew ? "新建脚本" : "编辑脚本" }}</span>
        <span
          class="el-icon-close g9 f26 poi"
          @click="showVisible = false"
        ></span>
      </div>
    </div>

    <el-form class="pl30 pr30" :model="formData" ref="form" label-width="120px">
      <el-form-item
        label="脚本编码"
        prop="code"
        :rules="[
          { required: true, message: '脚本编码不能为空', trigger: 'change' },
          {
            pattern: COMMON_CODE_64I_REG.pattern,
            message: '请输入有效的脚本编码',
            trigger: 'change',
          },
        ]"
      >
        <template
          slot="label"
        >脚本编码
          <el-tooltip
            popper-class="custom-popper"
            :content="COMMON_CODE_64I_REG.message"
            placement="top"
          >
            <i class="el-icon-question" />
          </el-tooltip>
        </template>
        <el-input
          :disabled="!isNew"
          v-model="formData.code"
          style="width: 400px"
          placeholder="请输入脚本编码"
          :maxlength="64"
          show-word-limit
        ></el-input>
      </el-form-item>

      <el-form-item
        label="脚本名称"
        prop="name"
        :rules="[
          { required: true, message: '脚本名称不能为空', trigger: 'change' },
        ]"
      >
        <el-input
          v-model="formData.name"
          style="width: 400px"
          placeholder="请输入脚本名称"
          :maxlength="64"
          show-word-limit
        />
      </el-form-item>

      <el-form-item label="脚本描述">
        <el-input
          type="textarea"
          v-model="formData.description"
          style="width: 400px"
          placeholder="请输入脚本描述"
          :maxlength="200"
          show-word-limit
        ></el-input>
      </el-form-item>

      <el-form-item
        label="脚本来源"
        prop="contentType"
        :rules="[
          { required: true, message: '请选择脚本来源', trigger: 'change' },
        ]"
      >
        <el-radio-group
          v-model="formData.contentType"
          @change="handleContentChange"
        >
          <el-radio
            v-for="(value, key) in SCRIPT_SOURCE_ENUM"
            :key="key"
            :label="key"
          >{{ value }}</el-radio
          >
        </el-radio-group>
      </el-form-item>

      <el-form-item
        label="脚本内容"
        prop="content"
        required
        :rules="[{ validator: contentValidator, trigger: 'change' }]"
      >
        <template
          slot="label"
        >脚本内容
          <el-tooltip
            popper-class="custom-popper"
            content="支持groovy脚本上传、编写"
            placement="top"
          >
            <i class="el-icon-question" />
          </el-tooltip>
        </template>
        <div v-if="formData.contentType === 'FILE'">
          <el-upload
            action=""
            accept=".groovy"
            :show-file-list="false"
            :http-request="handleHttpRequest"
            :beforeUpload="beforeUpload"
          >
            <template v-if="fileData.content">
              <span class="mr10">{{ fileData.content }}</span>
              <el-button key="1" icon="el-icon-upload2">重新上传</el-button>
            </template>
            <el-button
              v-else
              key="2"
              icon="el-icon-upload2"
            >上传脚本</el-button
            >
          </el-upload>
        </div>

        <div v-else>
          <template v-if="codeData.content">
            <el-tag
              class="mr10"
              style="font-weight: bold; color: #333"
              size="medium"
              type="info"
              disable-transitions
            >
              {{ codeData.type | scriptType }}
            </el-tag>
            <span class="mr10">{{ codeData.content | scriptValue }}</span>
            <el-button type="text" @click="handleCodeEdit">修改脚本</el-button>
          </template>
          <el-button
            v-else
            type="text"
            @click="handleCodeEdit"
          >编写脚本</el-button
          >
        </div>
      </el-form-item>
    </el-form>

    <div slot="footer" class="tr">
      <el-button @click="showVisible = false">取 消</el-button>
      <el-button type="primary" @click="submit">确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { GROOVY_TEMPLATE } from '@/utils/const'
import { COMMON_CODE_64I_REG } from '@/utils/reg'
import { SCRIPT_SOURCE_ENUM, SCRIPT_TYPE_ENUM } from '@/utils/enum'
import ScriptEditor from '@/components/ScriptEditor'
import { postHmscriptUpload,postHmscript,putHmscript } from '@/apis/paas/HmScriptController.js'

const defaultFormData = {
  contentType: Object.keys(SCRIPT_SOURCE_ENUM)[0]
}

export default {
  name: 'ScriptForm',
  data () {
    return {
      SCRIPT_SOURCE_ENUM,
      SCRIPT_TYPE_ENUM,
      COMMON_CODE_64I_REG,
      showVisible: false,
      formData: {},
      fileData: {}, // 文件来源的数据
      codeData: {} // 代码来源的数据
    }
  },

  computed: {
    isNew () {
      return !this.formData.id
    }
  },

  created () {},

  methods: {
    addForm (record = {}) {
      this.formData = {
        ...defaultFormData,
        ...record
      }
      this.fileData = {}
      this.codeData = {}
      return this.showModel()
    },

    editForm (record = {}) {
      const { type, contentType } = record
      let content = ''
      try {
        content = decodeURIComponent(record.content)
      } catch (err) {
        console.log(err)
      }
      this.formData = {
        ...record
      }

      // 数据分开存储 切换的时候保留
      if (contentType === 'FILE') {
        this.fileData = { type, content }
      } else if (contentType === 'CODE') {
        this.codeData = { type, content }
      }
      return this.showModel()
    },

    /**
     * record 详情数据
     * remote 是否远程加载
     */
    viewForm (record = {}, remote = false) {},
    showModel () {
      this.showVisible = true
      this.$nextTick(() => {
        this.$refs.form.clearValidate()
      })
      return {
        then: (callback) => {
          if (typeof callback === 'function') {
            this.callback = callback
          }
        }
      }
    },

    contentValidator (rule, value, callback) {
      const { contentType } = this.formData
      if (contentType === 'FILE' && !this.fileData.content) {
        callback(new Error('请上传脚本'))
      } else if (contentType === 'CODE' && !this.codeData.content) {
        callback(new Error('脚本不能为空'))
      } else {
        callback()
      }
    },

    handleContentChange () {
      // 切换来源是重置内容的校验
      this.$refs.form.clearValidate('content')
    },

    handleCodeEdit () {
      const { type, content } = this.codeData
      ScriptEditor.open(
        {
          title: '编写脚本',
          language: type,
          autoClose: true,
          content: content || GROOVY_TEMPLATE,
          showSelector: true
        },
        (data) => {
          const { content, language } = data
          this.$set(this.codeData, 'type', language)
          this.$set(this.codeData, 'content', content)
          this.$set(this.formData, 'content', content)
        }
      )
    },

    beforeUpload (file) {
      const type = file.name.split('.').pop().toLowerCase()
      if (['groovy'].includes(type)) {
        return true
      } else {
        this.$message.error('只能上传groovy格式的脚本')
        return false
      }
    },

    handleHttpRequest (param) {
      const file = param.file
      const size = 10
      const isEmpty = file.size / 1024 / 1024 === 0
      if (isEmpty) {
        this.$message.error(`文件不能为空`)
        return
      }
      const isLt = file.size / 1024 / 1024 < size
      if (!isLt) {
        this.$message.error(`文件大小不能超过 ${size}MB`)
        return
      }
      const formData = new FormData()
      formData.append('file', file)
      postHmscriptUpload(formData).then((res) => {
        const type = res.split('.').pop().toUpperCase()
        this.$set(this.fileData, 'content', res)
        this.$set(this.fileData, 'type', type)
        this.$set(this.formData, 'content', res)
      })
    },

    async submit () {
      try {
        await this.$refs.form.validate()
        const { id, code, name, description, contentType, folderId } =
          this.formData
        const { type, content } =
          contentType === 'FILE' ? this.fileData : this.codeData
        let params = {}
        let request = null
        if (this.isNew) {
          params = {
            code,
            name,
            description,
            contentType,
            type,
            folderId,
            content: encodeURIComponent(content)
          }
          request = postHmscript
        } else {
          params = {
            id,
            code,
            name,
            description,
            contentType,
            type,
            folderId,
            content: encodeURIComponent(content)
          }
          request = putHmscript
        }
        for (const key in params) {
          params[key] =
            typeof params[key] === 'string' ? params[key].trim() : params[key]
        }
        request(params).then((res) => {
          this.showVisible = false
          this.callback()
          // this.$emit('ok')
        })
      } catch (error) {
        console.log(error)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
